local PORT=8086
local NAME="sdtp"
local sdtp=Proto.new("sdtp", "china mobile private protocol")
--dofile(USER_DIR.."../../.local/lib/wireshark/plugins/sdtp_xdr.lua")
loadfile(USER_DIR.."../../.local/lib/wireshark/plugins/sdtp_xdr.lua")
-- print(USER_DIR)
-- print(DATA_DIR)
-- print(Dir.personal_config_path())
-- print(Dir.personal_script_path())


local sdtp_msg_type = {
    [0x0001] = "version nego request",
    [0x8001] = "version nego response",
    [0x0002] = "link auth request",
    [0x8002] = "link auth response",
    [0x0005] = "notify xdr data request",
    [0x8005] = "notify xdr data response"
}

local sdtp_compress_flag = {
    [0] = "no compress",
    [1] = "dfa compress",
    [2] = "lzo compress",
    [3] = "gzip compress",
    [4] = "7z compress"
}

-- base.DEC 是十进制显示， base.HEX 我希望是16进制显示
local sdtp_total_len =  ProtoField.uint16("sdtp.total_len", "total_len", base.DEC) -- "不能有空格"
local sdtp_type =  ProtoField.uint16("sdtp.msg_type", "msg_type", base.HEX, sdtp_msg_type)
local sdtp_sequence = ProtoField.uint32("sdtp.sequence", "sequence", base.HEX)
local sdtp_cnt = ProtoField.uint8("sdtp.count", "count", base.DEC)
local sdtp_flag = ProtoField.uint8("sdtp.flag", "flag", base.DEC, sdtp_compress_flag)
local sdtp_payload = ProtoField.string("sdtp.payload", "payload")
--local sdtp_payload = ProtoField.new("payload", "payload", ftypes.STRING, "", base.NONE)

sdtp.fields = {sdtp_total_len, sdtp_type, sdtp_sequence, sdtp_cnt, sdtp_flag, sdtp_payload}


function sdtp_body_parse(buf, pinfo, tree)
    return 1
end

function sdtp.dissector(buf, pinfo, tree)
    pinfo.cols.protocol:set("sdtp protocol")
    local len = buf:len()
    local sdtptree=tree:add(sdtp, buf(0,len), "sdtp tree")
    local offset = 0

    local pdu_offset =  pinfo.desegment_offset or 0

    -- total len
    local sdtp_len = buf(offset, 2):uint() -- 协议总长
    local nxt_pdu = pdu_offset + sdtp_len                                    

    if (nxt_pdu > buf:len()) then 
        pinfo.desegment_len = nxt_pdu - buf:len()
        pinfo.desegment_offset = pdu_offset
        return
    end
    

    sdtptree:add(sdtp_total_len, buf(offset, 2))
    offset = offset + 2
    -- type
    local msg_type = buf(offset, 2):uint()
    sdtptree:add(sdtp_type, buf(offset, 2))
    offset = offset + 2
    -- sdtp_sequence
    sdtptree:add(sdtp_sequence, buf(offset, 4))
    offset = offset + 4
    -- sdtp_cnt
    local cnt = buf(offset, 1):uint() 
    sdtptree:add(sdtp_cnt, buf(offset, 1))
    offset = offset + 1
    -- sdtp flag
    sdtptree:add(sdtp_flag, buf(offset, 1))
    offset = offset + 1

    local left = buf:len() - offset
    -- 显示payload
    sdtptree:add(sdtp_payload, buf(offset, left), left.." bytes")

    if (msg_type == 0x0005) then
        -- 解析xdr
        local diss = Dissector.get("sdtp_xdr") 
        local i = 0
        while i < cnt do
            ret = Dissector.call(diss, buf(offset, left):tvb(), pinfo, sdtptree)
            if (ret < 0) then 
                return false
            end
            offset = offset + ret
            left = left - ret
            i = i + 1
        end
    end

end


-- function sdtp_parse(buf, pinfo, tree)
--     local len = buf:len()
--     local sdtptree=tree:add(sdtp, buf(0,len), "sdtp tree")
--     local offset = 0
-- 
--     -- total len
--     sdtptree:add(sdtp_total_len, buf(offset, 2))
--     offset = offset + 2
--     -- type
--     local msg_type = buf(offset, 2):uint()
--     sdtptree:add(sdtp_type, buf(offset, 2))
--     offset = offset + 2
--     -- sdtp_sequence
--     sdtptree:add(sdtp_sequence, buf(offset, 4))
--     offset = offset + 4
--     -- sdtp_cnt
--     local cnt = buf(offset, 1):uint() 
--     sdtptree:add(sdtp_cnt, buf(offset, 1))
--     offset = offset + 1
--     -- sdtp flag
--     sdtptree:add(sdtp_flag, buf(offset, 1))
--     offset = offset + 1
-- 
--     local left = buf:len() - offset
--     -- 显示payload
--     sdtptree:add(sdtp_payload, buf(offset, left), left.." bytes")
-- 
--     if (msg_type == 0x0005) then
--         -- 解析xdr
--         local diss = Dissector.get("sdtp_xdr") 
--         local i = 0
--         while i < cnt do
--             ret = Dissector.call(diss, buf(offset, left):tvb(), pinfo, sdtptree)
--             if (ret < 0) then 
--                 return false
--             end
--             offset = offset + ret
--             left = left - ret
--             i = i + 1
--         end
--     end
-- end

-- local need_pdu = false
-- local sdtp_msg_len = 0;
-- function sdtp.dissector(buf, pinfo, tree)
--     pinfo.cols.protocol:set("sdtp protocol")
--     local left_len = buf:len()
--     local offset = 0 
-- 
--     print("buf:len() == "..buf:len())
--     while true do
--         if (need_pdu == false) then
--             sdtp_msg_len = buf(offset, 2):uint()
--             print("sdtp_msg_len = "..sdtp_msg_len)
--         end
-- 
--         if (buf:len() < sdtp_msg_len) then -- 如果需要的长度不满足
--             pinfo.desegment_len  = sdtp_msg_len - buf:len() 
--             pinfo.desegment_offset = offset 
--             need_pdu = true
--             return
--         end
--         -- 解析单个sdtp 消息
--         sdtp_parse(buf(0,sdtp_msg_len):tvb(), pinfo, tree)
--         left_len = left_len - sdtp_msg_len
--         offset = offset + sdtp_msg_len
--         need_pdu = false;
--         -- 消息结束， 直接退出
--         if (left_len == 0) then return end
--     end
-- end

DissectorTable.get("tcp.port"):add(PORT,sdtp)
